package com.kcl.dfss.fragments;

import org.videolan.libvlc.IVideoPlayer;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcException;
import org.videolan.libvlc.LibVlcUtil;
import org.videolan.libvlc.util.VLCInstance;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.SurfaceHolder.Callback;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.kcl.dfss.AjustActivity;
import com.kcl.dfss.LocationService;
import com.kcl.dfss.LocationService.CameraConnectionCallback;
import com.kcl.dfss.R;
import com.kcl.dfss.VideoHistoryActivity;
import com.kcl.dfss.utils.AppUtils;
import com.kcl.dfss.view.AjustView;
import com.kcl.dfss.view.CarDistanceView;
import com.kcl.dfss.view.CameraView;

import com.kcl.dfss.xcamera.XCamAlgoResult;

public class SurveillanceFragment extends Fragment implements IVideoPlayer,
		OnClickListener {

	private static LibVLC mLibVLC = null;
	private CameraView mCameraView;
	private SurfaceHolder surfaceHolder = null;
	private Surface mSurface = null;
	private TextView mRealtime;
	// private TextView mSurveilance;
	private LinearLayout mRealtimeLayout;
	private FrameLayout jiankong_view;
	private LinearLayout jk_noconnect;
	private ImageView mAjustView;
	private ImageView mHistoryView;
	private ImageView mLeftLane;
	private ImageView mRightLane;
	private ImageView mCarState;
	private CarDistanceView mDistance;
	private TextView mStatusView;
	private int mVideoWidth = 0;
	private int mVideoHeight = 0;
	private int mVideoVisibleHeight = 0;
	private int mVideoVisibleWidth = 0;
	private int mSarNum = 0;
	private int mSarDen = 0;
	private boolean mShowSurveilance = true;
	private boolean cameraconnect = false;
	private boolean isLogin = false;
	private boolean gesture ;
	private String TAG = "SurveillanceFragment";
	// private String mRtspPath = "rtsp://10.0.0.43:8554/test";
	private String mRtspPath = "rtsp://192.168.1.1/LIVE_VGA";
	// private String mRtspPath = "rtsp://192.168.1.1/HI351XX_VGA";
	// private String mRtspPath =
	// "rtsp://218.204.223.237:554/live/1/66251FC11353191F/e7ooqwcfbqjoo80j.sdp";
	private static final int UPDATE_CAMERAVIEW = 0;
	private static final int UPDATE_SUVEILANCEVIEW = 1;

	private static final String tag = "SurveillanceFragment";

	// AjustLayout
	private LinearLayout mAdjustLayout = null;
	private LinearLayout mAdjustBack = null;
	private TextView mAdjustSave = null;
	private ImageView image_gesture = null;
	private AjustView mAdjustView = null;
	
	private XCamAlgoResult mResult = null;
	private int mSpeed = 0;
	private float mTime = 0.0f;
	private boolean isPaused = true;
	private CameraConnectionCallback mCallback = new CameraConnectionCallback() {

		@Override
		public void onCameraDisconnected() {
			// TODO Auto-generated method stub
			cameraconnect = false;
			if (mLibVLC.isPlaying())
				mLibVLC.pause();

		}

		@Override
		public void onCameraConnected() {
			// TODO Auto-generated method stub
			cameraconnect = true;
			if (!isPaused) {
				Log.d(TAG,"camera is connected, and view isvisible begin to play MRL");
				mLibVLC.playMRL(mRtspPath);
			}
		}
	};
	private XCamAlgoResult[] TestData = {
			new XCamAlgoResult(new int[] { 0, 0 }, new int[] { 0, 0 }, false,
					0, 1000, 100),
			new XCamAlgoResult(new int[] { 1, 0 }, new int[] { 0, 0 }, true, 0,
					85, 5),
			new XCamAlgoResult(new int[] { 1, 0 }, new int[] { 1, 0 }, true, 1,
					45, 3),
			new XCamAlgoResult(new int[] { 1, 0 }, new int[] { 2, 0 }, true, 2,
					15, 1),
			new XCamAlgoResult(new int[] { 1, 1 }, new int[] { 2, 2 }, true, 2,
					15, 1),
	// new XCamAlgoResult(new int[] {}, new int[] {}, haveCar,
	// warning_level, fcwdistanc, time),
	// new XCamAlgoResult(new int[] {}, new int[] {}, haveCar,
	// warning_level, fcwdistanc, time),
	// new XCamAlgoResult(new int[] {}, new int[] {}, haveCar,
	// warning_level, fcwdistanc, time),
	// new XCamAlgoResult(new int[] {}, new int[] {}, haveCar,
	// warning_level, fcwdistanc, time),
	};

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			Log.d(TAG, "mVideoWidth is " + mVideoWidth + " mVideoheight is "
					+ mVideoHeight);
			int code = msg.what;
			switch (code) {
			case UPDATE_CAMERAVIEW:
				changeSurfaceLayout();
				break;
			case UPDATE_SUVEILANCEVIEW:
				updateSuveilanceView();
				break;
			}
		}
	};

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.d(TAG, "onCreate");
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.layout_surveilance, container,
				false);

		mCameraView = (CameraView) view.findViewById(R.id.cameraview);

		// mSurveilance = (TextView) view.findViewById(R.id.surveilance);
		mRealtime = (TextView) view.findViewById(R.id.realtime);
		// mSurveilance.setOnClickListener(this);
		// mRealtime.setOnClickListener(this);

		mRealtimeLayout = (LinearLayout) view.findViewById(R.id.realtimelayout);
		jiankong_view = (FrameLayout) view.findViewById(R.id.jiankong_view);
		jk_noconnect = (LinearLayout) view.findViewById(R.id.jk_noconnect);

		final SharedPreferences preferences = getActivity().getSharedPreferences(
				"shared_login", 0);
		isLogin = preferences.getBoolean("login", false);
		gesture = preferences.getBoolean("gesture", true);

		mAdjustLayout = (LinearLayout)view.findViewById(R.id.adjustlayout);
		mAdjustBack = (LinearLayout)view.findViewById(R.id.adjust_back);
		mAdjustSave = (TextView)view.findViewById(R.id.adjust_save);  
		image_gesture = (ImageView) view.findViewById(R.id.image_gesture);
		mAdjustView = (AjustView)view.findViewById(R.id.ajustview);
		mAdjustSave.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				int[] array = new int[2];
				array = mAdjustView.getAjustResult();
			}
		});
		mAdjustBack.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				mAdjustLayout.setVisibility(View.GONE);
			}
			
		});
		mAdjustSave.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				mAdjustLayout.setVisibility(View.GONE);
			}
		});
		image_gesture.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				preferences.edit().putBoolean("gesture", false).commit();
				image_gesture.setVisibility(View.GONE);
			}
		});
		// cameraconnect = LocationService.getCamemraConnected();

		initVLCComponent();
		// if (cameraconnect) {
		// mLibVLC.playMRL(mRtspPath);
		// } else {
		// mCameraView.setBackgroundResource(R.drawable.video_no_connect);
		// }
		// creame
		mAjustView = (ImageView) view.findViewById(R.id.camera_adjust);
		mAjustView.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				// m.snapShot();
//				mCameraView.snapShot();
				mAdjustLayout.setVisibility(View.VISIBLE);
				gesture = preferences.getBoolean("gesture", true);
				if(gesture){
					image_gesture.setVisibility(View.VISIBLE);
				}else{
					image_gesture.setVisibility(View.GONE);
				}
			}
		});
		
		// history
		mHistoryView = (ImageView) view.findViewById(R.id.history_record);
		mHistoryView.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				startActivity(new Intent(getActivity(),
						VideoHistoryActivity.class));
			}
		});

		mLeftLane = (ImageView) view.findViewById(R.id.image_carlane_left);
		mRightLane = (ImageView) view.findViewById(R.id.image_carlane_right);
		mCarState = (ImageView) view.findViewById(R.id.image_carstate);
		mDistance = (CarDistanceView) view.findViewById(R.id.car_distance);
		mStatusView = (TextView) view.findViewById(R.id.statusview);
		mCarState.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				new Thread() {
					public void run() {
						int n = 0;
						while (n < TestData.length) {
							mResult = TestData[n];
							// 加判断
							if (LocationService.getLatestLocation() != null) {
								mSpeed = (int) (LocationService
										.getLatestLocation().getSpeed() / 3600000.0f);
							} else {
								mSpeed = 0;
							}
							mTime = LocationService.getRunningTime() / 3600.0f;
							mHandler.sendEmptyMessage(UPDATE_SUVEILANCEVIEW);
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							// 加判断
							if (LocationService.getLatestLocation() != null) {
								mSpeed = (int) LocationService
										.getLatestLocation().getSpeed();
							} else {
								mSpeed = 0;
							}
							n++;
						}
					}
				}.start();
			}
		});
		LocationService.addCameraCallback(mCallback);

		// 默认首先加载实时页面
		mRealtime.performClick();

		// initVLCComponent();
		return view;
	}

	public void initVLCComponent() {
		try {
			mLibVLC = VLCInstance.getLibVlcInstance(getActivity());
		} catch (LibVlcException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		surfaceHolder = mCameraView.getHolder();
		surfaceHolder.addCallback(mSurfaceCallback);
		mLibVLC.eventVideoPlayerActivityCreated(true);
	}

	private SurveillanceFragment getInstance() {
		return this;
	}

	private static class ConfigureSurfaceHolder {
		private final Surface surface;
		private boolean configured;

		private ConfigureSurfaceHolder(Surface surface) {
			this.surface = surface;
		}
	}

	private final SurfaceHolder.Callback mSurfaceCallback = new Callback() {
		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			if (mLibVLC != null) {
				final Surface newSurface = holder.getSurface();
				if (mSurface != newSurface) {
					mSurface = newSurface;
					Log.d(TAG, "surfaceChanged: " + mSurface);
					mLibVLC.attachSurface(mSurface, getInstance());
				}
			}
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			Log.d(TAG, "surfaceDestroyed");
			if (mLibVLC != null) {
				mSurface = null;
				mLibVLC.detachSurface();
			}
		}
	};

	private void changeSurfaceLayout() {
		int sw;
		int sh;

		// get screen size
		sw = getView().getWidth();
		sh = mCameraView.getHeight();
		if (mLibVLC != null && !mLibVLC.useCompatSurface())
			mLibVLC.setWindowSize(sw, sh);

		double dw = sw, dh = sh;
		boolean isPortrait;

		isPortrait = false;

		if (sw > sh && isPortrait || sw < sh && !isPortrait) {
			dw = sh;
			dh = sw;
		}

		// sanity check
		if (dw * dh == 0 || mVideoWidth * mVideoHeight == 0) {
			Log.e(TAG, "Invalid surface size");
			return;
		}

		// compute the aspect ratio
		double ar, vw;
		if (mSarDen == mSarNum) {
			/* No indication about the density, assuming 1:1 */
			vw = mVideoVisibleWidth;
			ar = (double) mVideoVisibleWidth / (double) mVideoVisibleHeight;
		} else {
			/* Use the specified aspect ratio */
			vw = mVideoVisibleWidth * (double) mSarNum / mSarDen;
			ar = vw / mVideoVisibleHeight;
		}

		// compute the display aspect ratio
		double dar = dw / dh;

		if (dar < ar)
			dh = dw / ar;
		else
			dw = dh * ar;

		SurfaceView surface;
		// FrameLayout surfaceFrame;
		//
		surface = mCameraView;
		// // surfaceFrame = mSurfaceFrame;
		//
		// // set display size
		LayoutParams lp = surface.getLayoutParams();
		lp.width = (int) Math.ceil(dw * mVideoWidth / mVideoVisibleWidth);
		lp.height = (int) Math.ceil(dh * mVideoHeight / mVideoVisibleHeight);
		surface.setLayoutParams(lp);
		// surfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
		// set frame size (crop if necessary)
		// lp = surfaceFrame.getLayoutParams();
		// lp.width = (int) Math.floor(dw);
		// lp.height = (int) Math.floor(dh);
		// surfaceFrame.setLayoutParams(lp);

		surface.invalidate();
	}

	@Override
	public void setSurfaceLayout(int width, int height, int visible_width,
			int visible_height, int sar_num, int sar_den) {
		Log.d(TAG, "setSurfaceLayout: " + width + "  " + height);
		mVideoHeight = height;
		mVideoWidth = width;
		mVideoVisibleHeight = visible_height;
		mVideoVisibleWidth = visible_width;
		mSarNum = sar_num;
		mSarDen = sar_den;
		// Message msg = mHandler.obtainMessage(SURFACE_LAYOUT);
		// mHandler.sendMessage(msg);
		mHandler.sendEmptyMessage(UPDATE_CAMERAVIEW);
	}

	public void onPause() {
		super.onPause();
		Log.d(TAG, "onPause");
		mLibVLC.destroy();
		isPaused = true;
	}

	@SuppressLint("NewApi")
	public void onResume() {
		super.onResume();
		Log.d(TAG,"onResume");
		isPaused = false;
		cameraconnect = LocationService.getCamemraConnected();
		if (cameraconnect) {
			mCameraView.setBackground(null);
			try {
				mLibVLC = VLCInstance.getLibVlcInstance(getActivity());
			} catch (LibVlcException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			mLibVLC.eventVideoPlayerActivityCreated(true);
			mLibVLC.playMRL(mRtspPath);
		} else {
			mCameraView.setBackgroundResource(R.drawable.video_no_connect);
		}
	}

	public void onDestroy() {
		super.onDestroy();
		mLibVLC.destroy();
		LocationService.removeCameraCallback(mCallback);
	}

	@Override
	public void onClick(View v) {
		/*
		 * switch (v.getId()) { case R.id.surveilance: cameraconnect =
		 * LocationService.getCamemraConnected(); showSurveilance(); break; case
		 * R.id.realtime: cameraconnect = LocationService.getCamemraConnected();
		 * showRealtime(); break; default: break; }
		 */
	}

	/*
	 * @SuppressLint("NewApi") private void showSurveilance() { if
	 * (!mShowSurveilance) { if (isLogin) { if (cameraconnect) {
	 * jiankong_view.setVisibility(View.VISIBLE);
	 * mRealtimeLayout.setVisibility(View.GONE);
	 * jk_noconnect.setVisibility(View.GONE);
	 * mSurveilance.setBackgroundResource(R.drawable.slider);
	 * mRealtime.setBackground(null); mShowSurveilance = true; } else {
	 * jiankong_view.setVisibility(View.GONE);
	 * mRealtimeLayout.setVisibility(View.GONE);
	 * jk_noconnect.setVisibility(View.VISIBLE);
	 * mSurveilance.setBackgroundResource(R.drawable.slider);
	 * mRealtime.setBackground(null); mShowSurveilance = true; } } else {
	 * AppUtils.showdialog(getActivity()); } } }
	 */

	/*
	 * @SuppressLint("NewApi") private void showRealtime() { if
	 * (mShowSurveilance) { jiankong_view.setVisibility(View.GONE);
	 * mRealtimeLayout.setVisibility(View.VISIBLE);
	 * jk_noconnect.setVisibility(View.GONE); mSurveilance.setBackground(null);
	 * mRealtime.setBackgroundResource(R.drawable.slider); mShowSurveilance =
	 * false; } }
	 */

	private void updateSuveilanceView() {
		if (mResult == null) {
			return;
		}
		updateCarView(mResult.have_egolane_vehicle, mResult.fcw_warning_level,
				mResult.fcw_distance, mResult.fcw_ttc);
		updateLaneView(mResult.lane_active, mResult.lane_warning_flag);

		Log.i(tag, String.format(
				getResources().getString(R.string.surveilance_text), mSpeed,
				mTime));

		mStatusView.setText(String.format(
				getResources().getString(R.string.surveilance_text), mSpeed,
				mTime));
	}

	private void updateCarView(boolean front_car, int level,
			float fcw_distance, float fcw_time) {
		int imageid = R.drawable.normal_car_state;
		if (front_car) {
			switch (level) {
			case 0:
				imageid = R.drawable.normal_car_state;
				mDistance.setWarningInfo(fcw_distance, level);
				break;
			case 1:
				imageid = R.drawable.warning_car_state;
				mDistance.setWarningInfo(fcw_distance, level);
				break;
			case 2:
				imageid = R.drawable.red_warning_car_state;
				mDistance.setWarningInfo(fcw_time, level);
				break;
			}
		} else {
			imageid = R.drawable.no_car_state;
		}
		mCarState.setImageResource(imageid);

	}

	private void updateLaneView(int[] active, int[] warning_flag) {
		int imageid = R.drawable.normal_lane_left;
		if (active[0] == 0) {
			imageid = R.drawable.no_lane_left;
		} else {
			switch (warning_flag[0]) {
			case 0:
				imageid = R.drawable.normal_lane_left;
				break;
			case 1:
				imageid = R.drawable.warning_lane_left;
				break;
			case 2:
				imageid = R.drawable.red_warning_lane_left;
				break;
			default:
				break;
			}
		}
		mLeftLane.setImageResource(imageid);
		imageid = R.drawable.normal_lane_right;
		if (active[1] == 0) {
			imageid = R.drawable.no_lane_right;
		} else {
			switch (warning_flag[1]) {
			case 0:
				imageid = R.drawable.normal_lane_right;
				break;
			case 1:
				imageid = R.drawable.warning_lane_right;
				break;
			case 2:
				imageid = R.drawable.red_warning_lane_right;
				break;
			default:
				break;
			}
		}
		mRightLane.setImageResource(imageid);
	}

	@Override
	public void eventHardwareAccelerationError() {
		// TODO Auto-generated method stub

	}

	@Override
	public int configureSurface(Surface surface, final int width,
			final int height, final int hal) {
		// TODO Auto-generated method stub
		if (LibVlcUtil.isICSOrLater() || surface == null)
			return -1;
		if (width * height == 0)
			return 0;
		Log.d(TAG, "configureSurface: " + width + "x" + height);

		final ConfigureSurfaceHolder holder = new ConfigureSurfaceHolder(
				surface);

		final Handler handler = new Handler(Looper.getMainLooper());
		handler.post(new Runnable() {
			@Override
			public void run() {
				if (mSurface == holder.surface && surfaceHolder != null) {
					if (hal != 0)
						surfaceHolder.setFormat(hal);
					surfaceHolder.setFixedSize(width, height);
				}

				synchronized (holder) {
					holder.configured = true;
					holder.notifyAll();
				}
			}
		});

		try {
			synchronized (holder) {
				while (!holder.configured)
					holder.wait();
			}
		} catch (InterruptedException e) {
			return 0;
		}
		return 1;
	}

	// @Override
	// public void setSurfaceLayout(int arg0, int arg1, int arg2, int arg3,
	// int arg4, int arg5) {
	// // TODO Auto-generated method stub
	//
	// }
}
